package cn.kgc.commons.advice;

import cn.kgc.base.entity.SysLog;
import cn.kgc.base.mapper.SysLogMapper;
import cn.kgc.commons.annotation.DictLog;
import cn.kgc.commons.util.SpringContextUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;

/**
 * @description: 记录用户的操作日志信息
 * @author: 石浩杰
 * @date: 2022-11-28 10:40
 */
@Aspect
@Component
@Slf4j
public class AutoLogAdvice {
    @Pointcut("@annotation(cn.kgc.commons.annotation.DictLog)")
    public void autoLogPointCut(){}

    @Resource
    private SysLogMapper sysLogMapper;

    @Around("autoLogPointCut()")
    public Object autoLogAround(ProceedingJoinPoint joinPoint) throws Throwable{
        //获得开始的执行时间
        long startTime=System.currentTimeMillis();
        //调用目标方法
        Object result=joinPoint.proceed();
        //获得目标方法执行结束的时间
        long endTime=System.currentTimeMillis();
        //获得消耗时间
        long costTime=endTime-startTime;
        //记录日志信息
        saveLog(joinPoint,costTime);
        return result;
    }

    /**
     * 记录日志信息
     * @param joinPoint 切入点
     * @param costTime 目标方法的执行时间
     */
    private void saveLog(ProceedingJoinPoint joinPoint,long costTime){
        //获得切入点的方法
        MethodSignature methodSignature=(MethodSignature) joinPoint.getSignature();
        Method method=methodSignature.getMethod();
        //获得方法上的注解信息
        DictLog dictLog=method.getAnnotation(DictLog.class);
        String logContent=dictLog.logContent();
        int logType=dictLog.logType().getLogType();
        String moduleName=dictLog.moduleName().getName();
        int operateType=dictLog.operateType().getOperateType();
        //获得目标方法的名字
        String className=joinPoint.getTarget().getClass().getName();
        //获得目标方法的名字
        String methodName=className+"."+method.getName();
        //获得请求地址
        HttpServletRequest httpServletRequest=SpringContextUtils.getHttpServletRequest();
        String requestUrl=httpServletRequest.getRequestURL().toString();
        //todo 从请求中获得用户的ID和用户名
        Long userId=0L;
        String userName="";
        SysLog sysLog= SysLog.builder().costTime(costTime)
                .logContent(logContent)
                .logType(logType)
                .method(methodName)
                .moudulename(moduleName)
                .operateType(operateType)
                .userId(userId)
                .userName(userName)
                .requestUrl(requestUrl).build();
        log.info("日志增强类获得的日志信息:{}",sysLog);
        sysLogMapper.insert(sysLog);

    }
}
